﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.Xml;

namespace  Lcygcc.Application.WCF.Service
{
    public class WCFServiceHost
    {
        private string strBaseServiceUrl = "http://127.0.0.1:1234/MyWCFServer";//= ConfigurationManager.AppSettings["ServiceUrl"].ToString();

        private static WCFServiceHost m_WCFServiceHost;
        private WCFServiceHost()
        {

        }

        public static WCFServiceHost Instance()
        {
            if(m_WCFServiceHost == null)
            {
                m_WCFServiceHost = new WCFServiceHost();
            }
            return m_WCFServiceHost;
        }

        //启动所有的服务
        public void StartServices()
        {
            //1.读取此程序集里面的有服务契约的接口和实现类
            var assembly = Assembly.Load(typeof(WCFServiceHost).Namespace);
            var lstType = assembly.GetTypes();
            var lstTypeInterface = new List<Type>();
            var lstTypeClass = new List<Type>();
            foreach (var oType in lstType)
            {
                //2.通过接口上的特性取到需要的接口和实现类
                var lstCustomAttr = oType.CustomAttributes;
                if (lstCustomAttr.Count() <= 0)
                {
                    continue;
                }
                var oInterfaceServiceAttribute = lstCustomAttr.FirstOrDefault(x => x.AttributeType.Equals(typeof(ServiceInterfaceAttribute)));
                if (oInterfaceServiceAttribute != null)
                {
                    lstTypeInterface.Add(oType);
                    continue;
                }
                var oClassServiceAttribute = lstCustomAttr.FirstOrDefault(x => x.AttributeType.Equals(typeof(ServiceClassAttribute)));
                if (oClassServiceAttribute != null)
                {
                    lstTypeClass.Add(oType);
                }                
            }


            //var lstTypeClassTmp = lstTypeClass.Where(x => x.GetInterface(lstTypeInterface[0].Name) != null).ToList();
            //if (lstTypeClassTmp.Count <= 0)
            //{
            //    return;
            //}
            //if (lstTypeClassTmp[0].GetInterface(lstTypeInterface[0].Name).Equals(lstTypeInterface[0]))
            //{
            //    var oTask = Task.Factory.StartNew(() =>
            //    {
            //        OpenService(strBaseServiceUrl + "/" + lstTypeInterface[0].Name, lstTypeInterface[0], lstTypeClassTmp[0]);
            //    });
            //}


            //3.启动所有服务
            foreach (var oInterfaceType in lstTypeInterface)
            {
                var lstTypeClassTmp = lstTypeClass.Where(x => x.GetInterface(oInterfaceType.Name) != null).ToList();
                if (lstTypeClassTmp.Count <= 0)
                {
                    continue;
                }
                if (lstTypeClassTmp[0].GetInterface(oInterfaceType.Name).Equals(oInterfaceType))
                {
                    var oTask = Task.Factory.StartNew(() =>
                    {
                        OpenService(strBaseServiceUrl + "/" + oInterfaceType.Name, oInterfaceType, lstTypeClassTmp[0]);
                    });
                }
            }
        }

        //通过服务接口类型和实现类型启动WCF服务
        private void OpenService(string strServiceUrl, Type typeInterface, Type typeclass)
        {
            Uri httpAddress = new Uri(strServiceUrl);
            ServiceHost myServiceHost = new ServiceHost(typeclass);
            BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
            basicHttpBinding.MaxReceivedMessageSize = 2147483647L;
            basicHttpBinding.TransferMode = TransferMode.Streamed;
            basicHttpBinding.MaxBufferSize = 2147483647;
            basicHttpBinding.MaxBufferPoolSize = 2147483647L;
            basicHttpBinding.ReaderQuotas = new XmlDictionaryReaderQuotas
            {
                MaxStringContentLength = 2147483647
            };
            basicHttpBinding.SendTimeout = new TimeSpan(0, 0, 10);
            myServiceHost.AddServiceEndpoint(typeInterface, basicHttpBinding, httpAddress);
            ServiceMetadataBehavior serviceMetadataBehavior = new ServiceMetadataBehavior();
            serviceMetadataBehavior.HttpGetEnabled = true;
            serviceMetadataBehavior.HttpGetUrl = new Uri(strServiceUrl);
            myServiceHost.Description.Behaviors.Add(serviceMetadataBehavior);
            ServiceThrottlingBehavior serviceThrottlingBehavior = new ServiceThrottlingBehavior();
            serviceThrottlingBehavior.MaxConcurrentSessions = 1000;
            myServiceHost.Description.Behaviors.Add(serviceThrottlingBehavior);
            //  WCFEventServerHost.IServerEvent = mIServer;
            myServiceHost.Open();
            myServiceHost.Opened += delegate
            {
                Console.ForegroundColor = ConsoleColor.DarkRed;
                Console.WriteLine("服务启动成功。服务地址：" + strServiceUrl);
            };
            //while (true)
            //{
            //    Console.ReadLine();
            //}



            //Uri httpAddress = new Uri(strServiceUrl);
            //using (ServiceHost host = new ServiceHost(typeof(FactoryLayoutWCFService), new Uri[0]))//需要添加System.SystemModel这个dll。。。。CSOAService这个为实现ICSOAService的实现类，WCF真正的实现方法再这个类里面
            //{
            //    ///////////////////////////////////////添加服务节点///////////////////////////////////////////////////
            //    host.AddServiceEndpoint(typeInterface, new WSHttpBinding(), httpAddress);//ICSOAService这个为向外暴露的接口
            //    if (host.Description.Behaviors.Find<ServiceMetadataBehavior>() == null)
            //    {
            //        ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
            //        behavior.HttpGetEnabled = true;
            //        behavior.HttpGetUrl = httpAddress;
            //        host.Description.Behaviors.Add(behavior);
            //    }
            //    host.Opened += delegate
            //    {
            //        Console.ForegroundColor = ConsoleColor.Green;
            //        Console.WriteLine("服务启动成功。服务地址：" + strServiceUrl);
            //    };

            //    host.Open();
            //    while (true)
            //    {
            //        Console.ReadLine();
            //    }
            //}
        }
    }
}
